﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Estimate
{
    public partial class formProductOutcomeDetail : FormMDIChildTemplate
    {
        public formProductOutcomeDetail()
        {
           
        }
        InvoiceOutcome invoiceOutcome;
        InvoiceWriteoff invoiceWriteoff; 
        public formProductOutcomeDetail(InvoiceOutcome invoiceOutcome)
        {
            InitializeComponent();
            this.invoiceOutcome = invoiceOutcome;
           
        }

        private void formProductOutcomeDetail_Load(object sender, EventArgs e)
        {
            this.Text = String.Format("Накладна №{0} від {1}",
                invoiceOutcome.InvoiceOutcomeNumber, invoiceOutcome.DateCreate.ToShortDateString());

            this.invoiceWriteoff = GetInvoiceWriteoff();
            FillProduct();
            FillInvoiceOutcomes();
            root.TranslateGrid(gridInvoice);
            root.TranslateGrid(gridProduct);
            if (!invoiceOutcome.IsPay) buttonPrint2.Enabled = false;
            else buttonPay.Visible = false;
        }

        private InvoiceWriteoff GetInvoiceWriteoff()
        {
            var invoiceWriteOffs = context.InvoiceWriteoffs.Where(x => x.InvoiceWriteoffID == invoiceOutcome.InvoiceWriteoffID);
            if (invoiceWriteOffs.Count() == 0)
            {
                InvoiceWriteoff invoiceWriteOff = new InvoiceWriteoff();
                invoiceWriteOff.InvoiceWriteoffNumber = 1;
                if (context.InvoiceWriteoffs.Count() > 0)
                    invoiceWriteOff.InvoiceWriteoffNumber =
                        context.InvoiceWriteoffs.Max(x => x.InvoiceWriteoffNumber) + 1;
                invoiceWriteOff.DateCreate = invoiceOutcome.DateCreate;
                invoiceWriteOff.StoreHouse = invoiceOutcome.StoreHouse;
                invoiceWriteOff.Remark = "Видаткова Накладна №" + invoiceOutcome.InvoiceOutcomeNumber;
                invoiceWriteOff.InvoiceRelocationID = null;
                context.InvoiceWriteoffs.InsertOnSubmit(invoiceWriteOff);
                root.Submit(false);
                invoiceOutcome.InvoiceWriteoff = invoiceWriteOff;
                root.Submit();
                return invoiceWriteOff;
            }
            else return invoiceWriteOffs.First();
        }


        private void FillProduct()
        {
            var storeHouse = invoiceOutcome.StoreHouse;
            IQueryable<Product> products = context.Products;

            if (textBoxProductName.Text.Length > 0)
                products = products.Where(x => x.ProductName.Contains(textBoxProductName.Text));
            if (textBoxProductCode.Text.Length > 0)
                products = products.Where(x => x.ProductCode.Contains(textBoxProductCode.Text));

            var productsInStoreHouse = products.Select
                (product => new ProductInStoreHouseAndBudget
                {
                    ProductCode = product.ProductCode,
                    ProductId = product.ProductID,
                    ProductName = product.ProductName,
                    Unit = product.Unit
                }).ToList();
            foreach (var productInStoreHouse in productsInStoreHouse)
            {
                var cntIn =
                    storeHouse.ProductHistories.Where(
                        x =>
                        x.StatusID == 20 && x.StoreHouse == storeHouse &&
                        x.ProductID == productInStoreHouse.ProductId).Sum(
                        x => x.Cnt);
                var cntOut =
                    storeHouse.ProductHistories.Where(
                        x =>
                        x.StatusID == 30 && x.StoreHouse == storeHouse &&
                        x.ProductID == productInStoreHouse.ProductId).Sum(
                        x => x.Cnt);

                var cnt = cntIn - cntOut;

                productInStoreHouse.Count = cnt;
                productInStoreHouse.BudgetCount = invoiceOutcome.Object.BudgetProducts.Where
                    (x => x.ProductID == productInStoreHouse.ProductId).Sum(x => x.cnt);
            }
            productInStoreHouseAndBudgetBindingSource.DataSource =
                productsInStoreHouse.Where(x => x.Count > 0).ToList();
           // gridProduct.DataSource = productsInStoreHouse;
        }



        private void buttonAdd_Click(object sender, EventArgs e)
        {
            decimal count;
            try { count = decimal.Parse(textBoxCount.Text); }
            catch { return; }

            ProductInStoreHouseAndBudget productInStoreHouseAndBudget =
                (ProductInStoreHouseAndBudget)productInStoreHouseAndBudgetBindingSource.Current;
            if (productInStoreHouseAndBudget == null || count > productInStoreHouseAndBudget.Count) return;
            Product product = context.Products.Where(x => x.ProductID ==
                productInStoreHouseAndBudget.ProductId).First();

            List<InvoiceIncomePrice> prices = context.InvoiceIncomePrices.Where
                (x => x.InvoiceIncomeToHistory.ProductHistory.Product == product).OrderByDescending(x => x.DateSet).
                ToList();
            int priceIndex = 0;
            decimal totalCount = 0;
            for (int i = 0; i < prices.Count; i++)
            {
                totalCount += prices[i].Count;
                if (totalCount > count) { priceIndex = i; break; }
            }
            
            for (int i = 0; i <=priceIndex  ; i++)
            {
                decimal currentCount = prices[i].Count;
                if (count < prices[i].Count) currentCount = count;
                count = count - prices[i].Count;
                decimal price = prices[i].Price + prices[i].Price/100*invoiceOutcome.Object.Rate.RateValue;

                InvoiceWriteoffToHistory invoiceWriteoffToHistory = null;
                if (invoiceOutcome.IsPay)
                {
                    ProductHistory historyWritteOff = new ProductHistory();
                    historyWritteOff.Cnt = currentCount;
                    historyWritteOff.DateSet = invoiceOutcome.DateCreate;
                    historyWritteOff.Product = product;
                    historyWritteOff.StatusID = 30;
                    historyWritteOff.StoreHouse = invoiceOutcome.StoreHouse;
                    root.Submit(false);

                    invoiceWriteoffToHistory = new InvoiceWriteoffToHistory();
                    //invoiceWriteoffToHistory.InvoiceWriteoff = invoiceOutcome.InvoiceWriteoff;
                    invoiceWriteoffToHistory.ProductHistory = historyWritteOff;
                    invoiceWriteoffToHistory.Count = currentCount;
                    invoiceWriteoffToHistory.Price = price * db.Dollar;
                    invoiceWriteoffToHistory.PriceTotal = decimal.Round(price * db.Dollar * currentCount , 3);
                    invoiceWriteoffToHistory.InvoiceRelocationToHistoryID = null;

                    invoiceWriteoff.InvoiceWriteoffToHistories.Add(invoiceWriteoffToHistory);

                    root.Submit();
                }

                ProductHistory historyOutcome = new ProductHistory();
                historyOutcome.Cnt = currentCount;
                historyOutcome.DateSet = invoiceOutcome.DateCreate;
                historyOutcome.Product = product;
                historyOutcome.StatusID = 40;
                historyOutcome.StoreHouseID = invoiceOutcome.StoreHouseID;
                root.Submit(false);

                InvoiceOutcomeToHistory invoiceOutcomeToHistory = new InvoiceOutcomeToHistory();
                invoiceOutcomeToHistory.ProductHistory = historyOutcome;
                invoiceOutcomeToHistory.InvoiceOutcome = invoiceOutcome;
                invoiceOutcomeToHistory.Count = currentCount;
                invoiceOutcomeToHistory.Price = price * db.Dollar;
                invoiceOutcomeToHistory.PriceTotal = decimal.Round(price * db.Dollar * currentCount , 3);
                if (invoiceOutcome.IsPay) invoiceOutcomeToHistory.InvoiceWriteoffToHistory = invoiceWriteoffToHistory;


            }
            root.Submit();

            FillInvoiceOutcomes();
            FillProduct();

        }
        

        private void FillInvoiceOutcomes()
        {
            var invoice = from invoiceOutcomeToHistories in context.InvoiceOutcomeToHistories
                          from histories in context.ProductHistories
                          where invoiceOutcomeToHistories.ProductHistory == histories && invoiceOutcomeToHistories.InvoiceOutcome==invoiceOutcome
                          select new ProductInInvoice
                          {
                              Count = invoiceOutcomeToHistories.Count,
                              InvoiceToHistoryID  = invoiceOutcomeToHistories.InvoiceOutcomeToHistoryID ,
                              Price = invoiceOutcomeToHistories.Price,
                              PriceTotal = invoiceOutcomeToHistories.PriceTotal,
                              ProductName = histories.Product.ProductName,
                              UnitName = histories.Product.Unit.UnitName
                          };
            productInInvoiceBindingSource .DataSource = invoice;
        }

        private void buttonRemove_Click(object sender, EventArgs e)
        {
            ProductInInvoice productInInvoice = (ProductInInvoice) productInInvoiceBindingSource.Current;
            
            if (productInInvoice != null) db.DeleteInvoiceOutcomeToHistory
               (db.GetInvoiceOutcomeToHistory(productInInvoice.InvoiceToHistoryID));
            FillInvoiceOutcomes();
            FillProduct(); 
        }

        private void buttonPay_Click(object sender, EventArgs e)
        {
            foreach(InvoiceOutcomeToHistory invoiceOutcomeToHistory in invoiceOutcome .InvoiceOutcomeToHistories )
            {
                ProductHistory productHistory = new ProductHistory();
                productHistory.Cnt =invoiceOutcomeToHistory.Count;
                productHistory.DateSet = invoiceOutcome.DateCreate;
                productHistory.Product = invoiceOutcomeToHistory.ProductHistory.Product;
                productHistory.StatusID = 30;
                productHistory.StoreHouse = invoiceOutcome.StoreHouse;

                InvoiceWriteoffToHistory invoiceWriteoffToHistory = new InvoiceWriteoffToHistory();
                invoiceWriteoffToHistory.Count = invoiceOutcomeToHistory.Count;
                invoiceWriteoffToHistory.InvoiceWriteoff = invoiceWriteoff;
                invoiceWriteoffToHistory.Price = invoiceOutcomeToHistory.Price;
                invoiceWriteoffToHistory.PriceTotal = invoiceOutcomeToHistory.PriceTotal;
                invoiceWriteoffToHistory.ProductHistory = productHistory;

                invoiceOutcomeToHistory.InvoiceWriteoffToHistory = invoiceWriteoffToHistory;
                invoiceWriteoff.InvoiceWriteoffToHistories.Add(invoiceWriteoffToHistory);
            }
            invoiceOutcome.IsPay = true;
            root.Submit();

            buttonPay.Visible = false;
            buttonPrint2.Enabled = true;
            FillProduct();
        }

        private void textBoxProductCode_TextChanged(object sender, EventArgs e)
        {
            FillProduct();
        }


        private enum ProductOutcomeReportType
        {
            Bill,
            Invoice
        } ;

        private void buttonPrint_Click(object sender, EventArgs e)
        {
            ShowReport(ProductOutcomeReportType.Bill);
        }

        private void buttonPrint2_Click(object sender, EventArgs e)
        {
            ShowReport(ProductOutcomeReportType.Invoice );
        }

        private void ShowReport(ProductOutcomeReportType productOutcomeReportType)
        {
            reportInvoiceOutcome reportInvoiceOutcome = new reportInvoiceOutcome();

            reportInvoiceOutcome.DataSource = productInInvoiceBindingSource;

            reportInvoiceOutcome.xrLabelFirmTo.Lines = db.GetFirmOwn().GetFullDescription();

            reportInvoiceOutcome.xrLabelFirmFrom.Lines = invoiceOutcome.Object.Firm.GetFullDescription();
            reportInvoiceOutcome.xrLabelPayer.Text = invoiceOutcome.Payer;
            reportInvoiceOutcome.xrLabelRemark.Text = invoiceOutcome.Remark;
            if(productOutcomeReportType ==ProductOutcomeReportType.Bill ) 
                reportInvoiceOutcome.xrLabelHead1.Text = "Рахунок - фактура №  " + invoiceOutcome.InvoiceOutcomeNumber;
            else reportInvoiceOutcome.xrLabelHead1.Text = "Видаткова Накладна №  " + invoiceOutcome.InvoiceOutcomeNumber;
            reportInvoiceOutcome.xrLabelHead2.Text = "від " + invoiceOutcome.DateCreate.ToShortDateString();
            reportInvoiceOutcome.xrLabelPDV.Text = invoiceOutcome.Vat.ToString();
            decimal sum = 0;
            foreach (ProductInInvoice productInInvoice in productInInvoiceBindingSource)
                sum += productInInvoice.PriceTotal;
            decimal vAT = sum / 100 * invoiceOutcome.Vat;
            decimal totalSum = vAT + sum;

            reportInvoiceOutcome.xrLabelTotal.Text = context.sfMoneyToWords(totalSum);
            reportInvoiceOutcome.xrLabelSum.Text = decimal.Round(sum, 3).ToString();
            reportInvoiceOutcome.xrLabelSumTotal.Text = decimal.Round(totalSum, 3).ToString();
            reportInvoiceOutcome.xrLabelVAT.Text = decimal.Round(vAT, 3).ToString();

            reportInvoiceOutcome.ShowPreview();
        }
    }
}
